﻿using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain;
using Volo.Abp.Domain.Entities;

namespace Volo.Abp.Domain.Repositories
{
    public interface IReadOnlyRepository<TEntity> : IReadOnlyBasicRepository<TEntity>
        where TEntity : class, IEntity
    {


        /// <summary>
        /// Gets a list of entities by the given <paramref name="predicate"/>.
        /// </summary>
        /// <param name="predicate">A condition to filter the entities</param>
        /// <param name="includeDetails">Set true to include details (sub-collections) of this entity</param>
        /// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
        Task<IEnumerable<TEntity>> GetListAsync(
            [NotNull] Expression<Func<TEntity, bool>> predicate,
            bool includeDetails = false,
            CancellationToken cancellationToken = default);
        Task<TResult> FindAsync<TResult>(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, TResult>> selectExpression, Expression<Func<TEntity, object>> sortExpression=null);
        Task<IDictionary<TKey, TResult>> GetDictionaryAsync<TKey, TResult>(Expression<Func<TEntity, bool>> whereExpression, Func<TEntity, TKey> keyExpression, Func<TEntity, TResult> resultExpression);
        Task<IDictionary<string, object>> GetDbDictionaryAsync(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> keyExpression, Expression<Func<TEntity, object>> resultExpression);
    }

    public interface IReadOnlyRepository<TEntity, TKey> : IReadOnlyRepository<TEntity>, IReadOnlyBasicRepository<TEntity, TKey>
        where TEntity : class, IEntity<TKey>
    {
    }
}
